package com.dziennik.wedkarza.database;


import java.util.ArrayList;
import java.util.List;

import com.dziennik.wedkarza.model.SlownikCodeFisheries;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class DatabaseAdapter {
	
	
	
	//Pole DEBUG_TAG nie jest wymagane, aczkolwiek przyda nam się później do wyświetlania komunikatów w LogCacie 
	//(za pomocą metody Log.d(…)).
	private static final String DEBUG_TAG = "SQLite";
	//DB_NAME to nazwa pliku, w którym przechowywana będzie nasza baza. 
	//Można go będzie odnaleźć w naszym urządzeniu, w katalogu: /data/data/<namespace aplikacji>/databases/.
	private static final String DB_NAME = "database.db";
    //Pole DB_VERSION w naszym przypadku będzie oznaczało wersję bazy danych.
	//Posłuży nam ono wtedy, gdy system będzie musiał rozpoznać czy struktura naszej bazy się zmieniła
	//i czy powinien dokonać aktualizacji.
	private static final int DB_VERSION = 2;
	//nazwa tabeli
	private static final String TABLE_NAME_SLOWNIK = "Slownik";
	//nazwa kolumny będącej indeksem naszej tabeli. Każde z nich posiada swoją nazwę (KEY_…)
	public static final String KEY_ID = "_id";
	//typ i dodatkowe właściwości (…_OPTIONS)
    public static final String ID_OPTIONS = "INTEGER PRIMARY KEY AUTOINCREMENT";
    //numer porządkowy kolumny (…_COLUMN – bardzo przydatny w momencie pobierania danych).
    public static final int ID_COLUMN = 0;
    //reszta kolumn tabeli wraz z parametrami przekazywanymi przy ich tworzeniu
    public static final String KEY_CODE_FISHERIES = "codeFisheries";
    public static final String CODE_FISHERIES_OPTIONS = "TEXT NOT NULL";
    public static final int CODE_FISHERIES_COLUMN = 1;
    
    //Tworzenie tabeli slownik w bazie
    private static final String DB_CREATE_SLOWNIK_TABLE = 
    		"CREATE TABLE " + TABLE_NAME_SLOWNIK + " (" +
    		KEY_ID  + " " + ID_OPTIONS + ", " +
    		KEY_CODE_FISHERIES + " " + CODE_FISHERIES_OPTIONS +
    ");";
    
    //usuwanie tabeli slownik w bazie
    private static final String DB_DROP_SLOWNIK_TABLE = 
    		"DROP TABLE IF EXISTS " + TABLE_NAME_SLOWNIK;
    
    
    //Dodajemy do klasy niezbędne pola do jej funkcjonowania
   
	private SQLiteDatabase db;
    private Context context;
    private DatabaseHelper dbHelper;
    
    //konstruktor
    public DatabaseAdapter (Context context) {
     this.context = context;
    }
  
   
    
   
    
   //Klasa DatabaseHelper, która dziedziczy po SQLiteOpenHelper jest mechanizmem tworzącym i/lub aktualizującym strukturę naszej bazy. 
    //Posiada ona dwie nadpisane metody
    
   /* onCreate(SQLiteDatabase db) – metoda wywoływana w momencie, gdy odwołujemy się do bazy danych, która jeszcze fizycznie nigdzie nie istnieje.
    * W naszym przypadku wykonujemy kod SQL, który stworzy naszą tabelę.
      onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) – metoda ściśle związana z wersją naszej bazy, zapisaną w stałej DB_VERSION.
      Wywoływana jest w momencie gdy w urządzeniu istnieje starsza wersja bazy, i służy do aktualizacji jej struktury, do wersji najnowszej.
      Uwaga – w naszym przypadku idziemy na łatwiznę, i każda nowa wersja bazy powoduje usunięcie starej tabeli, a następnie utworzenie nowej.
      Zaleca się jednak by w metodzie onUpgrade(…) przeprowadzać przepisanie danych do nowej wersji bazy, zamiast ich usuwanie.
   */
    
    private static class DatabaseHelper extends SQLiteOpenHelper {
    	
        public DatabaseHelper(Context context, String name,
                CursorFactory factory, int version) {
            super(context, name, factory, version);
        }

		@Override
		public void onCreate(SQLiteDatabase db) {
			Log.d(DEBUG_TAG, "Database creating..");
			db.execSQL(DB_CREATE_SLOWNIK_TABLE);
			Log.d(DEBUG_TAG, "Table " + TABLE_NAME_SLOWNIK + " ver." + DB_VERSION + " created");
		}
		
		
		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			Log.d(DEBUG_TAG, "Upgrading database..");
			db.execSQL(DB_DROP_SLOWNIK_TABLE);
			Log.d(DEBUG_TAG, "Table " + TABLE_NAME_SLOWNIK + " updated from ver." + oldVersion + " to ver." + newVersion);
			Log.d(DEBUG_TAG, "All data is lost.");
			onCreate(db);
		}
    }
    
    // Otwieramy połączenie z bazą danych
    /* Blok try/catch zastosowany został na wypadek gdyby w system nie mógł zwrócić pełnego dostępu (odczyt/zapis) do naszej bazy.
       Może się to zdarzyć np. gdy w naszym urządzeniu brakuje pamięci lub działa ona w trybie „tylko do odczytu”.
       W takim wypadku możemy jeszcze poratować się dostępem read only do naszej bazy.
    */    
    public DatabaseAdapter open(){
        dbHelper = new DatabaseHelper(context, DB_NAME, null, DB_VERSION);
        try {
            db = dbHelper.getWritableDatabase();
        } catch (SQLException e) {
            db = dbHelper.getReadableDatabase();
        }
        return this;
    }
    
    // zamykamy połączenie z bazą danych
    public void close() {
      dbHelper.close();    
    }
    
    
    
    
    //metoda dodawająca do tabeli Słownik rekord kodu łowiska
    //Metoda tworzy nowy wpis jedynie na podstawie ciągu znakowego codeFisheries, bowiem id jest generowane automatycznie
    //Do zapisywania danych (w zasadzie do przekazywania ich do zapytania) służy klasa ContentValues. Za pomocą metod put(…) umieszczamy w niej pary klucz-wartość (gdzie klucz jest nazwą kolumny w naszej tabeli).
    //Następnie cały zbiór takich wartości (w postaci obiektu ContentValues) przekazujemy do metody insert(…). Zwraca ona id ostatnio zapisanego wiersza, lub -1 w wypadku błędu 
    public long insertCodeFisheries(String codeFisheries) {
        ContentValues newCodeFisheriesValues = new ContentValues();
        newCodeFisheriesValues.put(KEY_CODE_FISHERIES, codeFisheries);
        return db.insert(TABLE_NAME_SLOWNIK, null, newCodeFisheriesValues);
    }
    
    //metoda aktualizująca dane w wierszu
    public boolean updateCodeFisheries(long id, String codeFisheries) {
    	//Warunek wstawiany do klauzuli WHERE
    	//String where = KEY_ID + "=" + id;
        ContentValues updateCodeFisheriesValues = new ContentValues();
    	updateCodeFisheriesValues.put(KEY_CODE_FISHERIES, codeFisheries);
    	//Aktualizujemy dane wiersza zgodnego ze zmienną where
    	return db.update(TABLE_NAME_SLOWNIK, updateCodeFisheriesValues, KEY_ID + "=" + id , null) > 0;
    }
    
  
    
    //metoda usuwajaca w tabeli Słownik rekord kodu łowiska
    public boolean deleteCodeFisheries(long id){
    	//Warunek wstawiany do klauzuli WHERE
        String where = KEY_ID + "=" + id;
        return db.delete(TABLE_NAME_SLOWNIK, where, null) > 0;
    }
    
    //metoda usuwajaca w tabeli Słownik wszystkie rekordy
    //Aby usunąć wszystkie wpisy w warunku where wpisujemy znak (czyli String nie int!) 1. 
    public void deleteAllCodeFisheries() {
        db.delete(TABLE_NAME_SLOWNIK, "1", null);
    }
    
  //Pobieranie wszystkich wpisów w postaci obiektu Cursor
    public Cursor getAllEntries() {
        String[] columns = {KEY_ID, KEY_CODE_FISHERIES};
        Cursor cursor = db.query(TABLE_NAME_SLOWNIK, columns, null, null, null, null, null);
        
        return cursor;  
    }
    
    
   
    
   /* Cursor jest klasą, której obiekty w systemie Android reprezentują wyniki zwracane przez zapytania do bazy danych.
    * Posiada ona kilka metod, które bardzo ułatwiają nawigację po zwróconych wierszach:

        moveToFirst() - przesuwa kursor na pierwszy wiersz zwróconego wyniku,
        moveToNext() - przesuwa kursor na następny wiersz wyniku,
        moveToPrevious() - j.w. - na poprzedni,
        moveToPosition() - przesuwa kursor na zadaną pozycję,
        getPosition() - zwraca aktualną pozycję obiektu Cursor.

        Ponadto system Android dostarcza nam metody do zarządzania kursorem:

        startManagingCursor() - integruje czas życia kursora z czasem życia aktywności w której się znajduje. Dzięki temu kiedy Aktywność zostanie wstrzymana, automatycznie wywołana zostaje metoda deactivate(), a gdy wznowiona - requery(). Pierwsza z nich sprawia, że wszelkie wywołania obiektu cursor kończą się niepowodzeniem, druga natomiast wyłącza ten stan (pozwala na wywołania) oraz odświeża dane, na które wskazuje obiekt Cursor.
        stopManagingCursor() - deintegruje czas życia kursora z czasem życia aktywności.

    */
    
    //Metoda pobierająca pojedynczy wpis zgodny z indeksem
    public SlownikCodeFisheries getEntry(long id) {
    	
		String[] columns = {KEY_ID, KEY_CODE_FISHERIES};
		String where = KEY_ID + "=" + id;
		
		Cursor cursor = db.query(TABLE_NAME_SLOWNIK, columns, where, null, null, null, null, null);
		
		SlownikCodeFisheries name = null;
		
		if(cursor != null && cursor.moveToFirst()) {
			
			String getName = cursor.getString(CODE_FISHERIES_COLUMN);
			name = new SlownikCodeFisheries(id, getName);
		}
		return name;
	}
    
    
    //Getting All List Code Fisheries
    public List<SlownikCodeFisheries> getAllCodeFisheries() {
	List<SlownikCodeFisheries> SlownikCodeFisheriesList = new ArrayList<SlownikCodeFisheries>();
	// Select All Query
	String selectQuery = "SELECT  * FROM " + TABLE_NAME_SLOWNIK;

	//SQLiteDatabase db = this.getWritableDatabase();
	Cursor cursor = db.rawQuery(selectQuery, null);

	//looping through all rows and adding to list
	if (cursor.moveToFirst()) {
	    do {
	    SlownikCodeFisheries CodeFisheries = new SlownikCodeFisheries(Integer.parseInt(cursor
			.getString(0)), cursor.getString(1));
    //Adding contact to list
		SlownikCodeFisheriesList.add(CodeFisheries);
	    } while (cursor.moveToNext());
	}
	return SlownikCodeFisheriesList;
    }
    
    
    
}
